home *** CD-ROM | disk | FTP | other *** search
/ Mac-Source 1994 July / Mac-Source_July_1994.iso / C and C++ / Compilers⁄Interps / GCC-2.3.3r12 / Sources-Targets / mpw.h < prev    next >
Encoding:
Text File  |  1993-06-24  |  33.9 KB  |  1,020 lines  |  [TEXT/MPS ]

  1. /* Definitions of target machine for GNU compiler.  For Macintosh MPW.
  2.    Copyright (C) 1987, 1988 Free Software Foundation, Inc.
  3.    Copyright (C) 1989, 1990, 1992 Apple Computer, Inc.
  4.  
  5. This file is part of GNU CC.
  6.  
  7. GNU CC is free software; you can redistribute it and/or modify
  8. it under the terms of the GNU General Public License as published by
  9. the Free Software Foundation; either version 1, or (at your option)
  10. any later version.
  11.  
  12. GNU CC is distributed in the hope that it will be useful,
  13. but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15. GNU General Public License for more details.
  16.  
  17. You should have received a copy of the GNU General Public License
  18. along with GNU CC; see the file COPYING.  If not, write to
  19. the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  20.  
  21. /* Make sure we don't incorporate any of the bloated Sun FPA stuff. */
  22.  
  23. #undef SUPPORT_SUN_FPA
  24.  
  25. /* In general, syntax follows Mororola, */
  26.  
  27. #define MOTOROLA
  28.  
  29. /* ... but with some peculiarities. */
  30.  
  31. #define MPW_ASM
  32.  
  33. #define ONLY_INT_FIELDS
  34.  
  35. #define DEFAULT_SHORT_ENUMS 0
  36.  
  37. /* Include the base 68k definition file, since many tm.h bits are
  38.    identical across versions of the 68k architecture. */
  39.  
  40. #include "m68k.h"
  41.  
  42. #define SANE_FLOAT_FORMAT 3
  43. #define TARGET_FLOAT_FORMAT SANE_FLOAT_FORMAT
  44. #define HOST_FLOAT_FORMAT SANE_FLOAT_FORMAT
  45.  
  46. /* Get rid of that bothersome DATA directive before jump tables */
  47.  
  48. #define JUMP_TABLES_IN_TEXT_SECTION
  49.  
  50. #define CPP_SPEC "%{m68881:-Dmc68881}%{m68020:-Dmc68020}"
  51.  
  52. #define CC1_SPEC "%{s*}"
  53.  
  54. /* Names to predefine in the preprocessor for this target machine.  */
  55. /* Note that this is exactly MPW's set, plus something to distinguish */
  56. /* from "regular" MPW. */
  57.  
  58. #define CPP_PREDEFINES \
  59.   "-DMC68000 -Dmc68000 -Dm68k -Dmacintosh -Dapplec -Dmpwgcc"
  60.  
  61. /* This is true when code gen can treat symbol/label refs as constants. */
  62.  
  63. #define SYMBOLS_ARE_CONSTANTS 0
  64.  
  65. /* Define this when code labels and data labels need to be treated
  66.    differently in some way. */
  67.  
  68. #define MARK_LABEL_SECTION
  69.  
  70. /* So *library call generation* uses memcpy instead of bcopy, etc. */
  71.  
  72. #define TARGET_MEM_FUNCTIONS
  73.  
  74. /* Print subsidiary information on the compiler version in use.  */
  75. #undef  TARGET_VERSION
  76. #define TARGET_VERSION fprintf (stderr, " (680x0, MPW Asm syntax)");
  77.  
  78. /* Declare Mac-specific globals used in the compiler. */
  79. extern char *segment_name;
  80. extern int long_double_type_size;
  81. extern int current_static_decl;
  82. extern int current_function_is_pascal;
  83.  
  84. /* Should override defn in c-decl.c */
  85.  
  86. #define LONG_DOUBLE_TYPE_SIZE (long_double_type_size)
  87.  
  88. /* See m68k.h.  Default to plain 68000 + SANE + Macsbug symbols. */
  89.  
  90. #define TARGET_DEFAULT 062000
  91.  
  92. /* Mac-specific macros used in the machine description to test the flags.  */
  93. /* These are addons to the basic 68K set already defined. */
  94.  
  95. /* Include MacsBuggable symbols. */
  96. #define TARGET_MACSBUG (target_flags & 02000)
  97. /* Compile transcendental fns directly to 881 stuff. */
  98. #define TARGET_ELEMS881 (target_flags & 04000)
  99. /* Produce 32-bit references to global data. */
  100. #define TARGET_32BITDATA (target_flags & 010000)
  101. /* Generate code for SANE calls directly. */
  102. #define TARGET_SANE (target_flags & 020000)
  103. /* Generate code for integer library calls directly. */
  104. #define TARGET_INTLIB (target_flags & 040000)
  105. /* Generate pc-relative refs for strings after fn name. */
  106. #define TARGET_BSTR (target_flags & 0100000)
  107. /* Generate obscure addressing modifications. */
  108. #define TARGET_FX30 (target_flags & 0200000)
  109. /* Suppress all segment directives in the output. */
  110. #define TARGET_NOSEG (target_flags & 0400000)
  111.  
  112. #define TARGET_BFUN (target_flags & 01000000)
  113.  
  114. /* Macro to define tables used to set the flags.
  115.    This is a list in braces of pairs in braces,
  116.    each pair being { "NAME", VALUE }
  117.    where VALUE is the bits to set or minus the bits to clear.
  118.    An empty string NAME is used to identify the default VALUE.  */
  119.  
  120. /* The first part of this list (flags up to 01000 - note octalness) should be identical
  121.    to the generic 68k target. */
  122.  
  123. #undef  TARGET_SWITCHES
  124. #define TARGET_SWITCHES  \
  125.   { { "68020", 5},                \
  126.     { "c68020", 5},                \
  127.     { "68881", 2},                \
  128.     { "bitfield", 4},                \
  129.     { "68000", -5},                \
  130.     { "c68000", -5},                \
  131.     { "soft-float", -0102},            \
  132.     { "nobitfield", -4},            \
  133.     { "rtd", 8},                \
  134.     { "nortd", -8},                \
  135.     { "short", 040},                \
  136.     { "noshort", -040},                \
  137.     { "fpa", 0100},                \
  138.     { "nofpa", -0100},                \
  139.     { "sky", 0200},                \
  140.     { "nosky", -0200},                \
  141.     { "68020-40", 0407},                \
  142.     { "68030", -01400},                \
  143.     { "68030", 7},                \
  144.     { "68040", 01007},            \
  145.     { "bgfull", 02000 }, \
  146.     { "bgoff", -02000 }, \
  147.     { "elems881", 04000},  \
  148.     { "m", 010000},  \
  149.     { "sane", 020000 },  \
  150.     { "insane", -020000 },  \
  151.     { "nointlib", -040000 },  \
  152.     { "bstr", 0100000 },  \
  153.     { "fx30", 0200000 },  \
  154.     { "noseg", 0400000 },  \
  155.     { "bfun", 01000000 },  \
  156.     { "", TARGET_DEFAULT}}
  157.  
  158. /* In the MPW world, "long double" size depends on compiler flag (yech). */
  159. /* -elems881 implies -mc68881. */
  160. /* MPW Asm seems to require -mc68020 when doing large memory model (-m). */
  161. /* One or the other of sane/mc68881 must be on, but not both. */
  162.  
  163. #undef  OVERRIDE_OPTIONS
  164. #define OVERRIDE_OPTIONS        \
  165. {                    \
  166.   if (TARGET_ELEMS881) target_flags |= 2;  \
  167.   long_double_type_size = (TARGET_68881 ? 96 : 80);  \
  168.   mode_size[(int) XFmode] = (TARGET_68881 ? 12 : 10);  \
  169.   mode_unit_size[(int) XFmode] = (TARGET_68881 ? 12 : 10);  \
  170.   if (TARGET_68881) target_flags &= ~020000;  \
  171.   if (TARGET_SANE) target_flags &= ~2;  \
  172.   if (TARGET_32BITDATA) target_flags |= 5;  \
  173. }
  174.  
  175. /* (what *is* this?) */
  176. /* Define the largest mode that can be treated as a regular integer. */
  177.  
  178. /* MPW C tends to think of larger things as block mode objects, so we
  179.    should do this to maintain cross-callability. */
  180. #define MAX_FIXED_MODE_SIZE (GET_MODE_BITSIZE (SImode))
  181.  
  182. /* (should probably be scotched for MPW) */
  183. /* This defines the register which is used to hold the offset table for PIC. */
  184. /* #define PIC_OFFSET_TABLE_REGNUM 13 */
  185.  
  186. /* 1 for registers that have pervasive standard uses
  187.    and are not available for the register allocator.
  188.    On the 68000, only the stack pointer is such, but A5 is special to Macs. */
  189. #undef  FIXED_REGISTERS
  190. #define FIXED_REGISTERS  \
  191.  {0, 0, 0, 0, 0, 0, 0, 0, \
  192.   0, 0, 0, 0, 0, 1, 1, 1, \
  193.   0, 0, 0, 0, 0, 0, 0, 0, }
  194.  
  195. /* 1 for registers not available across function calls.
  196.    These must include the FIXED_REGISTERS and also any
  197.    registers that can be used without being saved.
  198.    The latter must include the registers where values are returned
  199.    and the register where structure-value addresses are passed.
  200.    Aside from that, you can include as many other registers as you like.  */
  201. /* This includes all of MPW's scratch registers. */
  202. #undef  CALL_USED_REGISTERS
  203. #define CALL_USED_REGISTERS \
  204.  {1, 1, 1, 0, 0, 0, 0, 0, \
  205.   1, 1, 0, 0, 0, 1, 1, 1, \
  206.   1, 1, 1, 1, 0, 0, 0, 0, }
  207.  
  208. /* Value is 1 if hard register REGNO can hold a value of machine-mode MODE.
  209.    On the 68000, the cpu registers can hold any mode but the 68881 registers
  210.    can hold only float modes.  And the 68881 registers can't hold anything
  211.    if 68881 use is disabled.  Actually, we have to exclude d6 and/or d7 if
  212.    we're using 2 or 3 registers to hold a value, since the "next" register(s)
  213.    would be a0/a1, and things would get really confusing. */
  214. #undef  HARD_REGNO_MODE_OK
  215. #define HARD_REGNO_MODE_OK(REGNO, MODE) \
  216.   (((REGNO) < 16 &&  \
  217.     ! (GET_MODE_SIZE (MODE) > 4 && (REGNO) >= 6) &&  \
  218.     ! (GET_MODE_SIZE (MODE) > 8 && (REGNO) >= 6))  \
  219.    || (TARGET_68881 && GET_MODE_CLASS (MODE) == MODE_FLOAT))
  220.  
  221. #if 0 /* (not sure if standard version legit tho) */
  222. /* Value is 1 if it is a good idea to tie two pseudo registers
  223.    when one has mode MODE1 and one has mode MODE2.
  224.    If HARD_REGNO_MODE_OK could produce different values for MODE1 and MODE2,
  225.    for any hard reg, then this must be 0 for correct output.
  226.  
  227.    Going by the above defn, we can tie modes for general regs (what about
  228.    d6/d7 tho?) and equal modes for float regs. */
  229. #define MODES_TIEABLE_P(MODE1, MODE2)            \
  230.    (TARGET_68881    ?                \
  231.    ((GET_MODE_CLASS (MODE1) == MODE_FLOAT)           \
  232.        == (GET_MODE_CLASS (MODE2) == MODE_FLOAT)) :  \
  233.    ((GET_MODE_SIZE (MODE1) < 8) && (GET_MODE_SIZE (MODE2) < 8)))
  234. #endif
  235.  
  236. /* Disables the assumption that symbols are constants. */
  237.  
  238. #define CONSTANT_P(X)   \
  239.   (GET_CODE (X) == LABEL_REF || GET_CODE (X) == SYMBOL_REF        \
  240.    || GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST_DOUBLE    \
  241.    || GET_CODE (X) == CONST || GET_CODE (X) == HIGH)
  242.  
  243. #undef    CONSTANT_ADDRESS_P
  244. #define CONSTANT_ADDRESS_P(X)                                           \
  245.   (CONSTANT_P (X) && (GET_CODE (X) != SYMBOL_REF))
  246.  
  247. /* Register in which address to store a structure value
  248.    arrives in the function.
  249.  
  250.    The MPW 3.0 calling convention is to have things on the stack top.  */
  251. #define STRUCT_VALUE_INCOMING    \
  252.    0
  253.    /*gen_rtx (MEM, Pmode, gen_rtx (PLUS, Pmode, frame_pointer_rtx,    \
  254.                  gen_rtx (CONST_INT, VOIDmode, 8)))*/
  255.  
  256. /* Place in which caller passes the structure value address.
  257.    Actually, all that matters about this value is it its rtx_code:
  258.    MEM means push the value on the stack like an argument.  */
  259. #define STRUCT_VALUE  \
  260.    0
  261.    /*gen_rtx (MEM, Pmode, gen_rtx (PRE_DEC, Pmode, stack_pointer_rtx))*/
  262.  
  263. /* To be MPW-compatible, multi-word structures cannot live in regs. */
  264.  
  265. #if 0
  266. #define RETURN_IN_MEMORY(TYPE) \
  267.   ((TREE_CODE (TYPE) == RECORD_TYPE || TREE_CODE (TYPE) == UNION_TYPE) && \
  268.    (GET_MODE_SIZE (TYPE_MODE (TYPE)) > UNITS_PER_WORD))
  269.  
  270. /* Pad shorts and chars upwards, but nobody else. */
  271.  
  272. #define FUNCTION_ARG_PADDING(MODE,SIZE)  \
  273.     (((MODE) == BLKmode                            \
  274.     ? (GET_CODE (SIZE) == CONST_INT                    \
  275.        && INTVAL (SIZE) < PARM_BOUNDARY / BITS_PER_UNIT)        \
  276.     : GET_MODE_BITSIZE (MODE) < PARM_BOUNDARY)                \
  277.    ? upward : none)
  278. #endif
  279.  
  280. #define MAXPARAMS 5
  281.  
  282. struct call_convention {
  283.   int pascalp;
  284.   int return_regno;
  285.   int parameter_regno[MAXPARAMS];
  286.   /* can flush these eventually */
  287.   struct parameter *last;
  288.   char name[1];
  289. };
  290.  
  291. #define SPECIAL_CALLING_CONVENTIONS struct call_convention
  292.  
  293. #define TYPE_CALL_CONVENTION_PASCAL(T) (TYPE_CALL_CONVENTION (T)->pascalp)
  294.  
  295. #define INIT_SPECIAL_CALLING_CONVENTIONS(T)  \
  296.     (TYPE_CALL_CONVENTION (T) =  \
  297.      (struct call_convention *) xmalloc (sizeof(struct call_convention)),  \
  298.      TYPE_CALL_CONVENTION (T)->pascalp = 0,  \
  299.      TYPE_CALL_CONVENTION (T)->return_regno = -1,  \
  300.      TYPE_CALL_CONVENTION (T)->parameter_regno[0] = -1,  \
  301.      TYPE_CALL_CONVENTION (T)->parameter_regno[1] = -1,  \
  302.      TYPE_CALL_CONVENTION (T)->parameter_regno[2] = -1,  \
  303.      TYPE_CALL_CONVENTION (T)->parameter_regno[3] = -1,  \
  304.      TYPE_CALL_CONVENTION (T)->parameter_regno[4] = -1)
  305.  
  306. #define COMPARE_CALL_CONVENTION(CC1,CC2)  \
  307.   (((CC1) == 0 && (CC2) == 0)  \
  308.    || ((CC1) != 0 && (CC2) != 0  \
  309.        && (CC1)->pascalp == (CC2)->pascalp  \
  310.        && (CC1)->return_regno == (CC2)->return_regno  \
  311.        && (CC1)->parameter_regno[0] == (CC2)->parameter_regno[0]  \
  312.        && (CC1)->parameter_regno[1] == (CC2)->parameter_regno[1]  \
  313.        && (CC1)->parameter_regno[2] == (CC2)->parameter_regno[2]  \
  314.        && (CC1)->parameter_regno[3] == (CC2)->parameter_regno[3]  \
  315.        && (CC1)->parameter_regno[4] == (CC2)->parameter_regno[4]))
  316.  
  317. #define COPY_CALL_CONVENTION(CC1,CC2)  \
  318.   { if ((CC1) != NULL && (CC2) != NULL)  \
  319.       {  \
  320. /*    (CC1)->pascalp = (CC2)->pascalp; should do? */  \
  321.     (CC1)->return_regno = (CC2)->return_regno;  \
  322.     (CC1)->parameter_regno[0] = (CC2)->parameter_regno[0];  \
  323.     (CC1)->parameter_regno[1] = (CC2)->parameter_regno[1];  \
  324.     (CC1)->parameter_regno[2] = (CC2)->parameter_regno[2];  \
  325.         (CC1)->parameter_regno[3] = (CC2)->parameter_regno[3];  \
  326.         (CC1)->parameter_regno[4] = (CC2)->parameter_regno[4]; } }
  327.  
  328. #define PRINT_CALL_CONVENTION(FILE,NODE,INDENT)  \
  329.   { struct call_convention *cc = TYPE_CALL_CONVENTION (NODE);  \
  330.     int i;  \
  331.     extern char *reg_names[];  \
  332.     if (cc->pascalp) fprintf(FILE, " pascal");  \
  333.     if (cc->return_regno >= 0)  \
  334.       fprintf (FILE, " return %s", reg_names[cc->return_regno]);  \
  335.     fprintf (FILE, " args");  \
  336.     for (i = 0; i < MAXPARAMS; ++i) { \
  337.       if (cc->parameter_regno[i] >= 0) \
  338.         fprintf (FILE, " %s", reg_names[cc->parameter_regno[i]]);  \
  339.     } \
  340.   }
  341.  
  342. /*   Always false on the Mac, even for pascal fns (really?). */
  343.  
  344. #undef  RETURN_POPS_ARGS
  345. #define RETURN_POPS_ARGS(FUNTYPE,SIZE) 0
  346.  
  347. /* On the Mac the return value is in D0 except for pascal routines, but
  348.    pascal fakes this, since space has to be reserved ahead of time, which
  349.    needs mods in the code proper. */
  350. /* 68881 functions return floats in FP0. */
  351.  
  352. #undef  FUNCTION_VALUE
  353. #define FUNCTION_VALUE(VALTYPE, FUNC) ((rtx) function_value (VALTYPE, FUNC))
  354.  
  355. #if 0 /* old */
  356. #define FUNCTION_VALUE(VALTYPE, FUNC)  \
  357.   gen_rtx (REG, TYPE_MODE (VALTYPE),  \
  358.        (TARGET_68881 &&  \
  359.         (GET_MODE_CLASS (TYPE_MODE (VALTYPE)) == MODE_FLOAT) ?  \
  360.         16 : 0))
  361. #endif
  362.  
  363. /* The actual offset gets filled after assign_parms is run... */
  364.  
  365. #define FUNCTION_OUTGOING_VALUE(VALTYPE, FUNC) \
  366.   ((rtx) function_outgoing_value (VALTYPE, FUNC))
  367.  
  368. #if 0
  369. #define FUNCTION_OUTGOING_VALUE(VALTYPE, FUNC) \
  370.   (((FUNC) && current_function_is_pascal) ?  \
  371.    gen_rtx (MEM, TYPE_MODE (VALTYPE),  \
  372.             gen_rtx (PLUS, Pmode,  \
  373.              frame_pointer_rtx,  \
  374.              gen_rtx (CONST_INT, VOIDmode, 12345))) :  \
  375.    FUNCTION_VALUE (VALTYPE, FUNC))
  376. #endif
  377.  
  378. /* Define how to find the value returned by a library function
  379.    assuming the value has mode MODE.  */
  380.  
  381. /* 1 if N is a possible register number for a function value.*/
  382. /* This is d0 or fp0. */
  383.  
  384. #undef  FUNCTION_VALUE_REGNO_P
  385. #define FUNCTION_VALUE_REGNO_P(N)  \
  386.   ((N) == 0 || (TARGET_68881 && (N) == 16))
  387.  
  388. /* MPW doesn't know diddly-squat about PCC. */
  389.  
  390. #undef PCC_STATIC_STRUCT_RETURN
  391.  
  392. #undef  FUNCTION_ARG
  393. #define FUNCTION_ARG(CUM, MODE, TYPE, NAMED)  \
  394.   ((rtx) function_arg (&CUM, MODE, NAMED))
  395.  
  396. #undef  FUNCTION_ARG_PARTIAL_NREGS
  397. #define FUNCTION_ARG_PARTIAL_NREGS(CUM, MODE, TYPE, NAMED) \
  398. ((0 /* TARGET_REGPARM */ && (CUM.size) < 8                    \
  399.   && 8 < ((CUM.size) + ((MODE) == BLKmode                \
  400.               ? int_size_in_bytes (TYPE)        \
  401.               : GET_MODE_SIZE (MODE))))          \
  402.  ? 2 - (CUM.size) / 4 : 0)
  403.  
  404. #if 0
  405. #define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) \
  406. (/* (TARGET_REGPARM && (CUM) < 8) ? gen_rtx (REG, (MODE), (CUM) / 4) : */ 0)
  407. #undef  FUNCTION_ARG_PARTIAL_NREGS
  408. #define FUNCTION_ARG_PARTIAL_NREGS(CUM, MODE, TYPE, NAMED) \
  409. ((0 /* TARGET_REGPARM */ && (CUM) < 8                    \
  410.   && 8 < ((CUM) + ((MODE) == BLKmode                \
  411.               ? int_size_in_bytes (TYPE)        \
  412.               : GET_MODE_SIZE (MODE))))          \
  413.  ? 2 - (CUM) / 4 : 0)
  414. #endif
  415.  
  416. /* Output assembler code to FILE to increment profiler label # LABELNO
  417.    for profiling a function entry.  */
  418.  
  419. #undef  FUNCTION_PROFILER
  420. #define FUNCTION_PROFILER(FILE, LABELNO)  \
  421.   fprintf (FILE, "\tlea LP%d,a0\n\tjsr fn##count\n", LABELNO)
  422.  
  423. /* Output assembler code to FILE to initialize this source file's
  424.    basic block profiling info, if that has not already been done.  */
  425.  
  426. #undef  FUNCTION_BLOCK_PROFILER
  427. #define FUNCTION_BLOCK_PROFILER(FILE, LABELNO)  \
  428.   fprintf (FILE, "\ttst.l LPBX0\n\tbne LPI%d\n", LABELNO);  \
  429.   fprintf (FILE, "\tpea LPBX0\n\tjsr bb##init\n\taddq.l #4,sp\n");  \
  430.   fprintf (FILE, "LPI%d:\n", LABELNO);
  431.  
  432. /* Output assembler code to FILE to increment the entry-count for
  433.    the BLOCKNO'th basic block in this source file.  */
  434.  
  435. #undef  BLOCK_PROFILER
  436. #define BLOCK_PROFILER(FILE, BLOCKNO)    \
  437.   fprintf (FILE, "\taddq.l #1,LPBX2+%d\n", 4 * BLOCKNO)
  438.  
  439. /* If the memory address ADDR is relative to the frame pointer,
  440.    correct it to be relative to the stack pointer instead.
  441.    This is for when we don't use a frame pointer.
  442.    ADDR should be a variable name.  */
  443.  
  444. #define FIX_FRAME_POINTER_ADDRESS(ADDR,DEPTH)  \
  445. { int offset = -1;                            \
  446.   rtx regs = stack_pointer_rtx;                        \
  447.   if (ADDR == frame_pointer_rtx)                    \
  448.     offset = 0;                                \
  449.   else if (GET_CODE (ADDR) == PLUS && XEXP (ADDR, 0) == frame_pointer_rtx \
  450.        && GET_CODE (XEXP (ADDR, 1)) == CONST_INT)            \
  451.     offset = INTVAL (XEXP (ADDR, 1));                    \
  452.   else if (GET_CODE (ADDR) == PLUS && XEXP (ADDR, 0) == frame_pointer_rtx) \
  453.     { rtx other_reg = XEXP (ADDR, 1);                    \
  454.       offset = 0;                            \
  455.       regs = gen_rtx (PLUS, Pmode, stack_pointer_rtx, other_reg); }    \
  456.   else if (GET_CODE (ADDR) == PLUS && XEXP (ADDR, 1) == frame_pointer_rtx) \
  457.     { rtx other_reg = XEXP (ADDR, 0);                    \
  458.       offset = 0;                            \
  459.       regs = gen_rtx (PLUS, Pmode, stack_pointer_rtx, other_reg); }    \
  460.   else if (GET_CODE (ADDR) == PLUS                    \
  461.        && GET_CODE (XEXP (ADDR, 0)) == PLUS                \
  462.        && XEXP (XEXP (ADDR, 0), 0) == frame_pointer_rtx        \
  463.        && GET_CODE (XEXP (ADDR, 1)) == CONST_INT)            \
  464.     { rtx other_reg = XEXP (XEXP (ADDR, 0), 1);                \
  465.       offset = INTVAL (XEXP (ADDR, 1));                    \
  466.       regs = gen_rtx (PLUS, Pmode, stack_pointer_rtx, other_reg); }    \
  467.   else if (GET_CODE (ADDR) == PLUS                    \
  468.        && GET_CODE (XEXP (ADDR, 0)) == PLUS                \
  469.        && XEXP (XEXP (ADDR, 0), 1) == frame_pointer_rtx        \
  470.        && GET_CODE (XEXP (ADDR, 1)) == CONST_INT)            \
  471.     { rtx other_reg = XEXP (XEXP (ADDR, 0), 0);                \
  472.       offset = INTVAL (XEXP (ADDR, 1));                    \
  473.       regs = gen_rtx (PLUS, Pmode, stack_pointer_rtx, other_reg); }    \
  474.   if (offset >= 0)                            \
  475.     { int regno;                            \
  476.       extern char call_used_regs[];                    \
  477.       for (regno = 16; regno < FIRST_PSEUDO_REGISTER; regno++)        \
  478.         if (regs_ever_live[regno] && ! call_used_regs[regno])        \
  479.           offset += 12;                            \
  480.       for (regno = 0; regno < 16; regno++)                \
  481.     if (regs_ever_live[regno] && ! call_used_regs[regno])        \
  482.       offset += 4;                            \
  483.       offset -= 4;                            \
  484.       ADDR = plus_constant (regs, offset + (DEPTH)); } }        \
  485.  
  486. /* Disable function cse even though it's good, because this screws up
  487.    direct functions and I'm too lazy to put in the exact test everywhere. */
  488.  
  489. #define NO_FUNCTION_CSE
  490.  
  491. /* (this probably needs work) */
  492.  
  493. /* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression
  494.    that is a valid memory address for an instruction.
  495.    The MODE argument is the machine mode for the MEM expression
  496.    that wants to use this address.
  497.  
  498.    The other macros defined here are used only in GO_IF_LEGITIMATE_ADDRESS.  */
  499.  
  500. /* See m68k.h, I am a little paranoid about MPW_C's macro expansion*/
  501.  
  502. #define ASM_IDENTIFY_GCC(FILE)  \
  503. { extern char *version_string;  \
  504.   fprintf((FILE), "; Compiled by MPW GCC %s\n", version_string);  }
  505.  
  506. /* Dump out all sorts of random header stuff that MPW wants. */
  507.  
  508. #undef  ASM_FILE_START
  509. #define ASM_FILE_START(FILE)  \
  510. {  \
  511.   init_import_for_file();  \
  512.   ASM_SEGMENT_NAME(FILE, segment_name);  \
  513.   if (TARGET_68040)  \
  514.     fprintf (FILE, "\tMACHINE MC68040\n");  \
  515.   else if (TARGET_68020)  \
  516.     fprintf (FILE, "\tMACHINE MC68020\n");  \
  517.   else  \
  518.     fprintf (FILE, "\tMACHINE MC68000\n");  \
  519.   if (TARGET_68881)  \
  520.     fprintf (FILE, "\tMC68881\n");  \
  521.   if (TARGET_32BITDATA && TARGET_68020)  \
  522.     fprintf (FILE, "\tFORWARD LONG\n");  \
  523.   fprintf (FILE, "\tSTRING ASIS\n");  \
  524.   fprintf (FILE, "\tCASE ON\n");  \
  525. }
  526.  
  527. /* Output to assembler file text saying following lines
  528.    may contain character constants, extra white space, comments, etc.  */
  529.  
  530. #undef  ASM_APP_ON
  531. #define ASM_APP_ON "; begin asm code\n"
  532.  
  533. /* Output to assembler file text saying following lines
  534.    no longer contain unusual constructs.  */
  535.  
  536. #undef  ASM_APP_OFF
  537. #define ASM_APP_OFF "; end asm code\n"
  538.  
  539. #define IMPORT_DECL(decl)  import_decl (decl);
  540.  
  541. #define ENCODE_SECTION_INFO(decl)  /*fprintf(stderr, "ENCODE:\n"); debug_tree (decl);*/
  542.  
  543. /* Defining this suppresses attempts to generate calls to `__main'. */
  544.  
  545. #define INIT_SECTION_ASM_OP
  546.  
  547. /* Output before read-only data.  */
  548.  
  549. #undef  TEXT_SECTION_ASM_OP
  550. #define TEXT_SECTION_ASM_OP "\tCODE"
  551.  
  552. /* Output before writable data.  */
  553.  
  554. #undef  DATA_SECTION_ASM_OP
  555. #define DATA_SECTION_ASM_OP "\tDATA"
  556. #undef READONLY_DATA_SECTION
  557. #define READONLY_DATA_SECTION data_section
  558.  
  559. /* Force all data thingies and variables to be data, except for strings
  560.    glued onto the end of function modules. */
  561.  
  562. #undef  SELECT_SECTION
  563. #define SELECT_SECTION(exp, reloc) 
  564.  
  565. /* The MPW proc declaration autoswitches to text section, so we need this
  566.    to tell GCC that this has happened. */
  567.  
  568. #define EXTRA_SECTION_FUNCTIONS  \
  569.   void force_text_section () { in_section = in_text; }
  570.  
  571. /* Note that PROC in MPW asm automatically declares CODE, so we
  572.    have to change the assumed section without writing the directive. */
  573.  
  574. #define ASM_PREDECLARE_FUNCTION_NAME(FILE,NAME,DECL)  \
  575. {  \
  576.   assemble_name (FILE, NAME);  \
  577.   fprintf (FILE, "%% \tPROC\n");  \
  578.   force_text_section ();  \
  579.   import_undefined (FILE);  \
  580.   FreeImps(); \
  581.   text_section();  \
  582. }
  583.  
  584. #define ASM_DECLARE_FUNCTION_NAME(FILE,NAME,DECL)  \
  585. {  \
  586.   if (TARGET_FX30)  \
  587.     fprintf (FILE, "\tIMPORT _StaticDataArea\n");  \
  588.   if ((DECL) && TREE_PUBLIC (DECL))   \
  589.     fprintf (FILE, "\tEXPORT ");  \
  590.   else  \
  591.     fprintf (FILE, "\tENTRY ");  \
  592.   assemble_name (FILE, NAME);  \
  593.   fprintf (FILE, "\n");  \
  594.   ASM_OUTPUT_LABEL (FILE, NAME);  \
  595. }
  596.  
  597. #define ASM_DECLARE_OBJECT_NAME(asm_out_file, name, decl) 
  598.  
  599. #define ASM_DECLARE_VARIABLE_NAME(FILE,NAME,PUBLIC)  \
  600. {  \
  601.   assemble_name (FILE, NAME);  \
  602.   fprintf (FILE, " \tRECORD");  \
  603.   if (PUBLIC)   \
  604.     fprintf (FILE, "\tEXPORT\n");  \
  605.   else  \
  606.     fprintf (FILE, "\tENTRY\n");  \
  607.   import_undefined (FILE);  \
  608. }
  609.  
  610. #define ASM_DECLARE_CONSTANT_NAME(FILE,NUM,EXP)  \
  611. {  char label[256];\
  612.   ASM_GENERATE_INTERNAL_LABEL (label, "LC", NUM);  \
  613.   if (! (TARGET_BSTR && TREE_CODE(EXP) == STRING_CST && current_function_decl && ! assembling_static_variable))  \
  614.     {  \
  615.       assemble_name (FILE, label);  \
  616.       fprintf (FILE, "\tRECORD\n");  \
  617.     }  \
  618. }
  619.  
  620. #define OUTPUT_LABELED_CONSTANT(asm_out_file,const_labelno,exp)  \
  621.   if (! (TARGET_BSTR  && TREE_CODE (exp) == STRING_CST && current_function_decl && ! assembling_static_variable))  \
  622.     {  \
  623.       output_constant (exp,  \
  624.            (TREE_CODE (exp) == STRING_CST  \
  625.             ? TREE_STRING_LENGTH (exp)  \
  626.             : int_size_in_bytes (TREE_TYPE (exp))));  \
  627.     }
  628.  
  629. #define REMEMBER_CONSTANT_LABEL(lbl,exp)  \
  630.   if (TARGET_BSTR && TREE_CODE (exp) == STRING_CST && current_function_decl && ! assembling_static_variable) \
  631.     record_a_string (lbl, TREE_STRING_POINTER (exp));
  632.  
  633. /* Exportation is done by general declaration macros. */
  634.  
  635. #undef GLOBAL_ASM_OP
  636. /*#define GLOBALS_ASM_OP ????*/
  637.  
  638. #undef  ASM_GLOBALIZE_LABEL
  639. #define ASM_GLOBALIZE_LABEL(FILE,NAME) /* */
  640.  
  641. #define ASM_OUTPUT_EXTERNAL(FILE,DECL,NAME)  ;
  642.  
  643. #if 0
  644. /* do this eventually */
  645. #define ASM_OUTPUT_EXTERNAL_LIBCALL(FILE, RTL) \
  646.   do { fputs ("\t.IMPORT ", FILE);                    \
  647.        assemble_name (FILE, XSTR ((RTL), 0));                       \
  648.        fputs (",CODE\n", FILE);                        \
  649.      } while (0)
  650. #endif
  651.  
  652. /* This is how to output the definition of a user-level label named NAME,
  653.    such as the label on a static function or variable NAME.  */
  654.  
  655. #undef  ASM_OUTPUT_LABEL
  656. #define ASM_OUTPUT_LABEL(FILE,NAME)    \
  657. { assemble_name (FILE, NAME); fputs (":\n", FILE); }
  658.  
  659. /* This is how to output a reference to a user-level label named NAME.
  660.    `assemble_name' uses this.  */
  661.  
  662. /* User-level labels (almost) always have one extra character that should
  663.    be ignored.  They may also conflict with MPW Asm register names. */
  664.  
  665. #undef  ASM_OUTPUT_LABELREF
  666. #define ASM_OUTPUT_LABELREF(FILE,NAME)  \
  667. {  \
  668.   extern char *avoid_mpw_register_name();  \
  669.   char *tname = avoid_mpw_register_name (NAME);  \
  670.   fprintf (FILE, "%s", tname);  \
  671. }
  672.  
  673. /* This is how to output an internal numbered label where
  674.    PREFIX is the class of label and NUM is the number within the class.  */
  675.  
  676. #undef  ASM_OUTPUT_INTERNAL_LABEL
  677. #define ASM_OUTPUT_INTERNAL_LABEL(FILE,PREFIX,NUM)    \
  678.   fprintf (FILE, "%s#%d:\n", PREFIX, NUM)
  679.  
  680. /* This is how to store into the string LABEL
  681.    the symbol_ref name of an internal numbered label where
  682.    PREFIX is the class of label and NUM is the number within the class.
  683.    This is suitable for output with `assemble_name'.  */
  684.  
  685. #undef  ASM_GENERATE_INTERNAL_LABEL
  686. #define ASM_GENERATE_INTERNAL_LABEL(LABEL,PREFIX,NUM)    \
  687.   sprintf (LABEL, "%s#%d", PREFIX, NUM)
  688.  
  689. /* This is how to output an assembler line defining a `float' constant.  */
  690.  
  691. #undef  ASM_OUTPUT_FLOAT
  692. #define ASM_OUTPUT_FLOAT(FILE,VALUE)  \
  693.   fprintf (FILE, "\tDC.S \"%.9g\"\n", (VALUE))
  694.  
  695. #undef  ASM_OUTPUT_DOUBLE
  696. #define ASM_OUTPUT_DOUBLE(FILE,VALUE)  \
  697.   fprintf (FILE, "\tDC.D \"%.20g\"\n", (VALUE))
  698.  
  699. #define ASM_OUTPUT_LONG_DOUBLE(FILE,VALUE)  \
  700.   output_mpw_long_double (FILE, VALUE)
  701.  
  702. /* This is how to output an assembler line defining an `int' constant.  */
  703.  
  704. #undef  ASM_OUTPUT_INT
  705. #define ASM_OUTPUT_INT(FILE,VALUE)  \
  706.  (fprintf (FILE, "\tDC.L "),            \
  707.   output_addr_const (FILE, (VALUE)),        \
  708.   fprintf (FILE, "\n"))
  709.  
  710. /* Likewise for `char' and `short' constants.  */
  711.  
  712. #undef  ASM_OUTPUT_SHORT
  713. #define ASM_OUTPUT_SHORT(FILE,VALUE)  \
  714.  (fprintf (FILE, "\tDC.W "),            \
  715.   output_addr_const (FILE, (VALUE)),        \
  716.   fprintf (FILE, "\n"))
  717.  
  718. #undef  ASM_OUTPUT_CHAR
  719. #define ASM_OUTPUT_CHAR(FILE,VALUE)  \
  720.  (fprintf (FILE, "\tDC.B "),            \
  721.   output_addr_const (FILE, (VALUE)),        \
  722.   fprintf (FILE, "\n"))
  723.  
  724. /* This is how to output an assembler line for a numeric constant byte.  */
  725.  
  726. #undef  ASM_OUTPUT_BYTE
  727. #define ASM_OUTPUT_BYTE(FILE,VALUE)  \
  728.   fprintf (FILE, "\tDC.B $%x\n", (VALUE))
  729.  
  730. /* This is how to output an insn to push a register on the stack.
  731.    It need not be very fast code.  */
  732.  
  733. #undef  ASM_OUTPUT_REG_PUSH
  734. #define ASM_OUTPUT_REG_PUSH(FILE,REGNO)  \
  735.   fprintf (FILE, "\tmove.l %s,-(sp)\n", reg_names[REGNO])
  736.  
  737. /* This is how to output an insn to pop a register from the stack.
  738.    It need not be very fast code.  */
  739.  
  740. #undef  ASM_OUTPUT_REG_POP
  741. #define ASM_OUTPUT_REG_POP(FILE,REGNO)  \
  742.   fprintf (FILE, "\tmove.l (sp)+,%s\n", reg_names[REGNO])
  743.  
  744. /* This is how to output an element of a case-vector that is absolute.
  745.    (The 68000 does not use such vectors,
  746.    but we must define this macro anyway.)  */
  747.  
  748. #undef  ASM_OUTPUT_ADDR_VEC_ELT
  749. #define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE)  \
  750.   fprintf (FILE, "\tDC.L L#%d\n", VALUE)
  751.  
  752. /* This is how to output an element of a case-vector that is relative.  */
  753.  
  754. #undef  ASM_OUTPUT_ADDR_DIFF_ELT
  755. #define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, VALUE, REL)  \
  756.   fprintf (FILE, "\tDC.W L#%d-L#%d\n", VALUE, REL)
  757.  
  758. /* This is how to output an assembler line
  759.    that says to advance the location counter
  760.    to a multiple of 2**LOG bytes.  */
  761.  
  762. #undef  ASM_OUTPUT_ALIGN
  763. #define ASM_OUTPUT_ALIGN(FILE,LOG)      \
  764.   if ((LOG) == 1)            \
  765.     fprintf (FILE, "\tALIGN 2\n");    \
  766.   else if ((LOG) != 0)            \
  767.     abort ();
  768.  
  769. /* A "skip" in MPW is better done by filling with zeros. */
  770.  
  771. #undef  ASM_OUTPUT_SKIP
  772. #define ASM_OUTPUT_SKIP(FILE,SIZE)  \
  773.   fprintf (FILE, "\tDCB.B %d,0\n", (SIZE))
  774.  
  775. /* This says how to output an assembler line
  776.    to define a global common symbol.  */
  777.  
  778. #undef  ASM_OUTPUT_COMMON
  779. #define ASM_OUTPUT_COMMON(FILE, NAME, SIZE, ROUNDED)  \
  780. do {  \
  781.   fprintf (FILE, "\n");  \
  782.   assemble_name (FILE, NAME);  \
  783.   fprintf (FILE, " \tRECORD\tEXPORT\n");  \
  784.   fprintf (FILE, "\tDS.B %d\n", ROUNDED);  \
  785.   fprintf (FILE, "\tENDR\t; ");  \
  786.   assemble_name (FILE, NAME);  \
  787.   fprintf (FILE, "\n");  \
  788. } while (0)
  789.  
  790. /* This says how to output an assembler line
  791.    to define a local common symbol.  */
  792.  
  793. #undef  ASM_OUTPUT_LOCAL
  794. #define ASM_OUTPUT_LOCAL(FILE, NAME, SIZE, ROUNDED)  \
  795. do {  \
  796.   assemble_name (FILE, NAME);  \
  797.   /*fprintf (FILE, " \tRECORD\tENTRY\n");*/  \
  798.   fprintf (FILE, "\tDS.B %d\n", ROUNDED);  \
  799.   /*fprintf (FILE, "\tENDR\t; "); */ \
  800.  /* assemble_name (FILE, NAME);*/  \
  801.   fprintf (FILE, "\n");  \
  802. } while (0)
  803.  
  804. /* Store in OUTPUT a string (made with alloca) containing
  805.    an assembler-name for a local static variable named NAME.
  806.    LABELNO is an integer which is different for each call.  */
  807.  
  808. #undef  ASM_FORMAT_PRIVATE_NAME
  809. #define ASM_FORMAT_PRIVATE_NAME(OUTPUT, NAME, LABELNO)    \
  810.  ((OUTPUT) = (char *) alloca (strlen ((NAME)) + 12),    \
  811.   sprintf ((OUTPUT), "%s___%d", (NAME), (LABELNO)))
  812.  
  813. /* MPW reverses the characters meaning newline and cr. */
  814.  
  815. #undef  TARGET_NEWLINE
  816. #define TARGET_NEWLINE 13
  817. #undef  TARGET_CR
  818. #define TARGET_CR 10
  819.  
  820. /* MPW strings need a dedicated routine to write them out properly. */
  821.  
  822. #define ASM_OUTPUT_ASCII(FILE,STRING,SIZE)  \
  823.   output_mpw_string (FILE, STRING, SIZE);
  824.  
  825. /* At the end of a function module, prepare for the next module. */
  826.  
  827. #define ASM_FUNCTION_END(FILE) \
  828. {  extern char *current_function_name; \
  829.    fprintf (FILE, "\tENDP\t; %s\n", current_function_name);  \
  830. }
  831.  
  832. /* At the end of a variable module, prepare for the next module. */
  833.  
  834. #define ASM_VARIABLE_END(FILE,NAME) \
  835. {  \
  836.    fprintf (FILE, "\tENDR\t; ");  \
  837.    assemble_name (FILE, NAME);  \
  838.    fprintf (FILE, "\n");  \
  839. }
  840.  
  841. /* At the end of a variable module, prepare for the next module. */
  842.  
  843. #define ASM_CONSTANT_END(FILE,NUM,EXP) \
  844.   if (! (TARGET_BSTR && TREE_CODE(EXP) == STRING_CST && current_function_decl && ! assembling_static_variable))  \
  845.     fprintf (FILE, "\tENDR\n");
  846.  
  847. /* Write out a segment name. */
  848.  
  849. #define ASM_SEGMENT_NAME(FILE,NAME)  \
  850.   if (! TARGET_NOSEG) fprintf(FILE, "\tSEG '%s'\n", NAME);
  851.  
  852. /* Write out an import of a name not in this module. */
  853.  
  854. #define ASM_IMPORT_NAME(FILE, NAME, DATA_P)  \
  855. { \
  856.   fprintf (FILE, "\tIMPORT ");  \
  857.   assemble_name (FILE, NAME);  \
  858.   if(DATA_P) \
  859.     fprintf(FILE, ":DATA\n"); \
  860.   else \
  861.     fprintf(FILE, ":CODE\n");\
  862. }
  863.  
  864. /* At the end of the whole file, spit out a last directive. */
  865.  
  866. #define ASM_FILE_END(FILE) \
  867.   fprintf(FILE, "\tEND\n");
  868.  
  869. /* Magic for the handling of 10/12 byte long doubles. */
  870.  
  871. #ifdef macintosh
  872.  
  873. #undef REAL_VALUE_TYPE
  874. #define REAL_VALUE_TYPE extended
  875. #define REAL_IS_NOT_DOUBLE
  876.  
  877. #define REAL_ARITHMETIC(value, code, x, y) mpw_real_arithmetic(&value, code, x, y)
  878. #define REAL_VALUE_TO_INT(low, high, x) mpw_real_to_int(&low, &high, x)
  879. #define REAL_VALUE_FROM_UNSIGNED_INT(x, low, high) \
  880.       x = (double) high;\
  881.       x *= ((double) ((HOST_WIDE_INT) 1 << (HOST_BITS_PER_WIDE_INT / 2))\
  882.         * (double) ((HOST_WIDE_INT) 1 << (HOST_BITS_PER_WIDE_INT / 2)));\
  883.       x += (double) (unsigned HOST_WIDE_INT) low;
  884. #define REAL_VALUE_FROM_INT(d, low, high) \
  885.       if (high < 0) \
  886.     { \
  887.       d = (double) (~ high); \
  888.       d *= ((double) ((HOST_WIDE_INT) 1 << (HOST_BITS_PER_WIDE_INT / 2)) \
  889.         * (double) ((HOST_WIDE_INT) 1 << (HOST_BITS_PER_WIDE_INT / 2))); \
  890.       d += (double) (unsigned HOST_WIDE_INT) (~ low); \
  891.       d = (- d - 1.0); \
  892.     } \
  893.       else \
  894.     { \
  895.       d = (double) high; \
  896.       d *= ((double) ((HOST_WIDE_INT) 1 << (HOST_BITS_PER_WIDE_INT / 2)) \
  897.         * (double) ((HOST_WIDE_INT) 1 << (HOST_BITS_PER_WIDE_INT / 2))); \
  898.       d += (double) (unsigned HOST_WIDE_INT) low; \
  899.     }
  900.  
  901.  
  902. int mpw_real_to_int(int *low, int *high, REAL_VALUE_TYPE x);
  903. int mpw_real_arithmetic(REAL_VALUE_TYPE *value,
  904.                     int code,
  905.                     REAL_VALUE_TYPE x,
  906.                     REAL_VALUE_TYPE y);
  907.  
  908. #endif /* macintosh */
  909.  
  910. /* Don't bother to try to do anything special.  Default will be to use
  911.    'double', which is adequate except for trying to cross-compile extended
  912.    float constants on a machine that doesn't support them, which I don't
  913.    want to bother with right now.  Note that cross-compilation of vars,
  914.    arith, etc, is still ok - only constants might be wrong. */
  915.  
  916.  
  917. /* Machinery to add math-oriented builtin functions. */
  918.  
  919. #define ADDITIONAL_BUILTINS  \
  920.   if (flag_apple && TARGET_ELEMS881)  \
  921.     {  \
  922.       builtin_function ("cos", extended_ftype_extended, BUILT_IN_COS, 0);  \
  923.       builtin_function ("sin", extended_ftype_extended, BUILT_IN_SIN, 0);  \
  924.       builtin_function ("tan", extended_ftype_extended, BUILT_IN_TAN, 0);  \
  925.       builtin_function ("asin", extended_ftype_extended, BUILT_IN_ASIN, 0);  \
  926.       builtin_function ("acos", extended_ftype_extended, BUILT_IN_ACOS, 0);  \
  927.       builtin_function ("atan", extended_ftype_extended, BUILT_IN_ATAN, 0);  \
  928.       builtin_function ("sinh", extended_ftype_extended, BUILT_IN_SINH, 0);  \
  929.       builtin_function ("cosh", extended_ftype_extended, BUILT_IN_COSH, 0);  \
  930.       builtin_function ("tanh", extended_ftype_extended, BUILT_IN_TANH, 0);  \
  931.       builtin_function ("exp", extended_ftype_extended, BUILT_IN_EXP, 0);  \
  932.       builtin_function ("log", extended_ftype_extended, BUILT_IN_LOG, 0);  \
  933.       builtin_function ("log10", extended_ftype_extended, BUILT_IN_LOG10, 0);  \
  934.       builtin_function ("sqrt", extended_ftype_extended, BUILT_IN_FSQRT, 0);  \
  935.     }
  936.  
  937. #define ADDITIONAL_BUILT_IN_CASES \
  938.     case BUILT_IN_TAN:  \
  939.     case BUILT_IN_ASIN:  \
  940.     case BUILT_IN_ACOS:  \
  941.     case BUILT_IN_ATAN:  \
  942.     case BUILT_IN_SINH:  \
  943.     case BUILT_IN_COSH:  \
  944.     case BUILT_IN_TANH:  \
  945.     case BUILT_IN_EXP:  \
  946.     case BUILT_IN_LOG:  \
  947.     case BUILT_IN_LOG10:
  948.     
  949. #define ADDITIONAL_BUILT_IN_OPS \
  950.     case BUILT_IN_TAN:  \
  951.       builtin_optab = tan_optab; break; \
  952.     case BUILT_IN_ASIN:  \
  953.       builtin_optab = asin_optab; break; \
  954.     case BUILT_IN_ACOS:  \
  955.       builtin_optab = acos_optab; break; \
  956.     case BUILT_IN_ATAN:  \
  957.       builtin_optab = atan_optab; break; \
  958.     case BUILT_IN_SINH:  \
  959.       builtin_optab = sinh_optab; break; \
  960.     case BUILT_IN_COSH:  \
  961.       builtin_optab = cosh_optab; break; \
  962.     case BUILT_IN_TANH:  \
  963.       builtin_optab = tanh_optab; break; \
  964.     case BUILT_IN_EXP:  \
  965.       builtin_optab = exp_optab; break; \
  966.     case BUILT_IN_LOG:  \
  967.       builtin_optab = log_optab; break; \
  968.     case BUILT_IN_LOG10:  \
  969.       builtin_optab = log10_optab; break;
  970.  
  971. /* Many pragmas to handle. */
  972.  
  973. /* Code to handle #pragma directives.  The interface is a bit messy,
  974.    but there's no simpler way to do this while still using yylex.  */
  975. /* This was taken from m88k.h. */
  976.  
  977. #define HANDLE_MPW_PRAGMA
  978.  
  979. #define HANDLE_SEGMENT_PRAGMA
  980.  
  981. #define APPLE_DEFAULT 1
  982.  
  983. #define DEFAULT_INCLUDE_ENV "CIncludes"
  984.  
  985. #undef PARM_BOUNDARY
  986. #define PARM_BOUNDARY 16
  987.  
  988. typedef struct cumargs {
  989.   int size;
  990.   int count;
  991.   struct call_convention *p;
  992. } CumArgs;
  993.  
  994. #undef  CUMULATIVE_ARGS
  995. #define CUMULATIVE_ARGS CumArgs
  996.  
  997. #undef  FUNCTION_ARG_ADVANCE
  998. #define FUNCTION_ARG_ADVANCE(CUM,MODE,TYPE,NAMED)    \
  999.     ((CUM).size += ((MODE) != BLKmode          \
  1000.      ? (GET_MODE_SIZE (MODE) + 3) & ~3   \
  1001.       : (int_size_in_bytes (TYPE) + 3) & ~3), (CUM).count += 1)
  1002.  
  1003. #undef  INIT_CUMULATIVE_ARGS
  1004. #define INIT_CUMULATIVE_ARGS(CUM,FNTYPE,LIBNAME)  \
  1005.     ((CUM).size = 0,  \
  1006.          (CUM).count = 0, \
  1007.          (CUM).p = ((FNTYPE) ? TYPE_CALL_CONVENTION (FNTYPE) : NULL))
  1008.  
  1009. /* Declarations of assorted functions called from the machine description. */
  1010.  
  1011. char *output_sane_convert();
  1012. char *output_sane_2();
  1013. char *output_sane_3();
  1014. char *output_sane_tst();
  1015. char *output_sane_cmp();
  1016. char *output_move_extended();
  1017. char *output_move_const_long_double();
  1018. char *output_lib_convert();
  1019. char *output_int_lib_call();
  1020.